home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Mail / pine3.92 / pico / spell.c < prev    next >
C/C++ Source or Header  |  1996-03-14  |  6KB  |  277 lines

  1. #if    !defined(lint) && !defined(DOS)
  2. static char rcsid[] = "$Id: spell.c,v 4.13 1996/03/15 07:41:11 hubert Exp $";
  3. #endif
  4. /*
  5.  * Program:    spell.c
  6.  *
  7.  *
  8.  * Michael Seibel
  9.  * Networks and Distributed Computing
  10.  * Computing and Communications
  11.  * University of Washington
  12.  * Administration Builiding, AG-44
  13.  * Seattle, Washington, 98195, USA
  14.  * Internet: mikes@cac.washington.edu
  15.  *
  16.  * Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  17.  *
  18.  *
  19.  * Pine and Pico are registered trademarks of the University of Washington.
  20.  * No commercial use of these trademarks may be made without prior written
  21.  * permission of the University of Washington.
  22.  * 
  23.  * Pine, Pico, and Pilot software and its included text are Copyright
  24.  * 1989-1996 by the University of Washington.
  25.  * 
  26.  * The full text of our legal notices is contained in the file called
  27.  * CPYRIGHT, included with this distribution.
  28.  *
  29.  */
  30.  
  31. #include <stdio.h>
  32. #include "osdep.h"
  33. #include "pico.h"
  34. #include "estruct.h"
  35. #ifdef    SPELLER
  36. #include "edef.h"
  37.  
  38.  
  39. #ifdef    ANSI
  40.     void chword(char *, char *);
  41.     int  movetoword(char *);
  42. #else
  43.     void chword();
  44.     int  movetoword();
  45. #endif
  46.  
  47.  
  48. #define  NSHLINES  12
  49.  
  50. static char *spellhelp[] = {
  51.   "Spell Check Help",
  52.   " ",
  53.   "\tThe spell checker examines all words in the text.  It then",
  54.   "\toffers each misspelled word for correction while simultaneously",
  55.   "\thighlighting it in the text.  To leave a word unchanged simply",
  56.   "~\thit ~R~e~t~u~r~n at the edit prompt.  If a word has been corrected,",
  57.   "\teach occurrence of the incorrect word is offered for replacement.",
  58.   " ",
  59.   "~\tSpell checking can be cancelled at any time by typing ~^~C (~F~3)",
  60.   "\tafter exiting help.",
  61.   " ",
  62.   "End of Spell Check Help",
  63.   " ",
  64.   NULL
  65. };
  66.  
  67.  
  68. static char *pinespellhelp[] = {
  69.   "Spell Check Help",
  70.   " ",
  71.   "\tThe spell checker examines all words in the text.  It then",
  72.   "\toffers each misspelled word for correction while simultaneously",
  73.   "\thighlighting it in the text.  To leave a word unchanged simply",
  74.   "\thit Return at the edit prompt.  If a word has been corrected,",
  75.   "\teach occurrence of the incorrect word is offered for replacement.",
  76.   " ",
  77.   "\tSpell checking can be cancelled at any time by typing ^C (F3)",
  78.   "\tafter exiting help.",
  79.   " ",
  80.   "End of Spell Check Help",
  81.   " ",
  82.   NULL
  83. };
  84.  
  85.  
  86.  
  87. /*
  88.  * spell() - check for potentially missspelled words and offer them for
  89.  *           correction
  90.  */
  91. spell(f, n)
  92. {
  93.     int    status, next, ret;
  94.     FILE   *p;
  95.     char   *b, *sp, *fn;
  96.     char   wb[NLINE], cb[NLINE];
  97.     char   *writetmp();
  98.     FILE   *P_open();
  99.  
  100.     setimark(0, 1);
  101.     emlwrite("Checking spelling...");         /* greetings */
  102.  
  103.     if(Pmaster && Pmaster->alt_spell)
  104.       return(alt_editor(1, 0));            /* f == 1 means fork speller */
  105.  
  106.     if((fn = writetmp(0, 0)) == NULL){
  107.     emlwrite("Can't write temp file for spell checker");
  108.     return(-1);
  109.     }
  110.  
  111.     if((sp = (char *)getenv("SPELL")) == NULL)
  112.       sp = SPELLER;
  113.  
  114.     sprintf(cb, "( %s ) < %s", sp, fn);        /* pre-use buffer! */
  115.     if((p = P_open(cb)) == NULL){         /* read output from command */
  116.     unlink(fn);
  117.     emlwrite("Can't fork spell checker", NULL);
  118.     return(-1);
  119.     }
  120.  
  121.     ret = 1;
  122.     while(fgets(wb, NLINE, p) != NULL && ret){
  123.     if((b = (char *)strchr(wb,'\n')) != NULL)
  124.       *b = '\0';
  125.     strcpy(cb, wb);
  126.  
  127.     gotobob(0, 1);
  128.  
  129.     status = TRUE;
  130.     next = 1;
  131.  
  132.     while(status){
  133.         if(next++)
  134.           if(movetoword(wb) != TRUE)
  135.         break;
  136.  
  137.         update();
  138.         (*term.t_rev)(1);
  139.         pputs(wb, 1);            /* highlight word */
  140.         (*term.t_rev)(0);
  141.  
  142.         if(strcmp(cb, wb)){
  143.         char prompt[2*NLINE + 32];
  144.         sprintf(prompt, "Replace \"%s\" with \"%s\"", wb, cb);
  145.         status=mlyesno(prompt, TRUE);
  146.         }
  147.         else
  148.           status=mlreplyd("Edit a replacement: ", cb, NLINE, QDEFLT, NULL);
  149.  
  150.  
  151.         curwp->w_flag |= WFMOVE;        /* put cursor back */
  152.         sgarbk = 0;                /* fake no-keymenu-change! */
  153.         update();
  154.         pputs(wb, 0);            /* un-highlight */
  155.  
  156.         switch(status){
  157.           case TRUE:
  158.         chword(wb, cb);            /* correct word    */
  159.           case FALSE:
  160.         update();            /* place cursor */
  161.         break;
  162.           case ABORT:
  163.         emlwrite("Spell Checking Cancelled", NULL);
  164.         ret = FALSE;
  165.         status = FALSE;
  166.         break;
  167.           case HELPCH:
  168.         if(Pmaster)
  169.           (*Pmaster->helper)(pinespellhelp, 
  170.                      "Help with Spelling Checker", 1);
  171.         else
  172.           pico_help(spellhelp, "Help with Spelling Checker", 1);
  173.           case (CTRL|'L'):
  174.         next = 0;            /* don't get next word */
  175.         sgarbf = TRUE;            /* repaint full screen */
  176.         update();
  177.         status = TRUE;
  178.         continue;
  179.           default:
  180.         emlwrite("Huh?");        /* shouldn't get here, but.. */
  181.         status = TRUE;
  182.         sleep(1);
  183.         break;
  184.         }
  185.         forwword(0, 1);            /* goto next word */
  186.     }
  187.     }
  188.     P_close(p);                    /* clean up */
  189.     unlink(fn);
  190.     swapimark(0, 1);
  191.     curwp->w_flag |= WFHARD|WFMODE;
  192.     sgarbk = TRUE;
  193.  
  194.     if(ret)
  195.       emlwrite("Done checking spelling");
  196.     return(ret);
  197. }
  198.  
  199.  
  200.  
  201.  
  202. /* 
  203.  * chword() - change the given word, wp, pointed to by the curwp->w_dot 
  204.  *            pointers to the word in cb
  205.  */
  206. void
  207. chword(wb, cb)
  208.   char *wb;                    /* word buffer */
  209.   char *cb;                    /* changed buffer */
  210. {
  211.     ldelete((long) strlen(wb), 0);        /* not saved in kill buffer */
  212.     while(*cb != '\0')
  213.       linsert(1, *cb++);
  214.  
  215.     curwp->w_flag |= WFEDIT;
  216. }
  217.  
  218.  
  219.  
  220.  
  221. /* 
  222.  * movetoword() - move to the first occurance of the word w
  223.  *
  224.  *    returns:
  225.  *        TRUE upon success
  226.  *        FALSE otherwise
  227.  */
  228. movetoword(w)
  229.   char *w;
  230. {
  231.     int      i;
  232.     int      ret  = FALSE;
  233.     int         olddoto;
  234.     LINE     *olddotp;
  235.     register int   off;                /* curwp offset */
  236.     register LINE *lp;                /* curwp line   */
  237.  
  238.     olddoto = curwp->w_doto;            /* save where we are */
  239.     olddotp = curwp->w_dotp;
  240.  
  241.     curwp->w_bufp->b_mode |= MDEXACT;        /* case sensitive */
  242.     while(forscan(&i, w, 1) == TRUE){
  243.     if(i)
  244.       break;                /* wrap NOT allowed! */
  245.  
  246.     lp  = curwp->w_dotp;            /* for convenience */
  247.     off = curwp->w_doto;
  248.  
  249.     /*
  250.      * We want to minimize the number of substrings that we report
  251.      * as matching a misspelled word...
  252.      */
  253.     if(off == 0 || !isalpha(lgetc(lp, off - 1).c)){
  254.         off += strlen(w);
  255.         if((!isalpha(lgetc(lp, off).c) || off == llength(lp)) 
  256.            && lgetc(lp, 0).c != '>'){
  257.         ret = TRUE;
  258.         break;
  259.         }
  260.     }
  261.  
  262.     forwchar(0, 1);                /* move on... */
  263.  
  264.     }
  265.     curwp->w_bufp->b_mode ^= MDEXACT;        /* case insensitive */
  266.  
  267.     if(ret == FALSE){
  268.     curwp->w_dotp = olddotp;
  269.     curwp->w_doto = olddoto;
  270.     }
  271.     else
  272.       curwp->w_flag |= WFHARD;
  273.  
  274.     return(ret);
  275. }
  276. #endif    /* SPELLER */
  277.